package com.ruoyi.redis.util;

import java.time.LocalDateTime;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;

/**
 * @Description: 关于缓存的相关问题 
 * @ClassName: CacheClient
 * @author syc
 * @date: 2022年6月9日 上午8:53:07
 * 1. 缓存更新 a.低一致性需求：使用Redis自带的内存淘汰机制b.高一致性需求：主动更新，并以超时剔除作为兜底方案
 *    读操作：缓存命中则直接返回, 缓存未命中则查询数据库，并写入缓存，设定超时时间
 *    写操作：先写数据库，然后再删除缓存,要确保数据库与缓存操作的原子性
 * 2. 缓存穿透  是指客户端请求的数据在缓存中和数据库中都不存在，这样缓存永远不会生效，这些请求都会打到数据库。
 * 3. 缓存雪崩
 * 4. 缓存击穿
 * 
 * 
 */
@Component
public class CacheClient {
	
//    private final StringRedisTemplate stringRedisTemplate;
//
//    private static final ExecutorService CACHE_REBUILD_EXECUTOR = Executors.newFixedThreadPool(10);
//
//    public CacheClient(StringRedisTemplate stringRedisTemplate) {
//        this.stringRedisTemplate = stringRedisTemplate;
//    }
//
//    public void set(String key, Object value, Long time, TimeUnit unit) {
//        stringRedisTemplate.opsForValue().set(key, JSONUtil.toJsonStr(value), time, unit);
//    }
//
//    public void setWithLogicalExpire(String key, Object value, Long time, TimeUnit unit) {
//        // 设置逻辑过期
//        RedisData redisData = new RedisData();
//        redisData.setData(value);
//        redisData.setExpireTime(LocalDateTime.now().plusSeconds(unit.toSeconds(time)));
//        // 写入Redis
//        stringRedisTemplate.opsForValue().set(key, JSONUtil.toJsonStr(redisData));
//    }
//
//    public <R,ID> R queryWithPassThrough(
//            String keyPrefix, ID id, Class<R> type, Function<ID, R> dbFallback, Long time, TimeUnit unit){
//        String key = keyPrefix + id;
//        // 1.从redis查询商铺缓存
//        String json = stringRedisTemplate.opsForValue().get(key);
//        // 2.判断是否存在
//        if (StrUtil.isNotBlank(json)) {
//            // 3.存在，直接返回
//            return JSONUtil.toBean(json, type);
//        }
//        // 判断命中的是否是空值
//        if (json != null) {
//            // 返回一个错误信息
//            return null;
//        }
//
//        // 4.不存在，根据id查询数据库
//        R r = dbFallback.apply(id);
//        // 5.不存在，返回错误
//        if (r == null) {
//            // 将空值写入redis
//            stringRedisTemplate.opsForValue().set(key, "", RedisConstants.CACHE_NULL_TTL, TimeUnit.MINUTES);
//            // 返回错误信息
//            return null;
//        }
//        // 6.存在，写入
//        this.set(key, r, time, unit);
//        return r;
//    }
//
//	

}
